
namespace ShoppingCart.DataAccess
{
	using System;
	using System.Collections.Generic;
	using System.Data;
	using System.Data.Common;
	using Microsoft.Practices.EnterpriseLibrary.Data;
	using ShoppingCart.Business.Entity;

	/// <summary>
	/// Represents the DataAccess of ClienteData.
	/// </summary>
	public class ClienteData : Singleton<ClienteData>
	{
		#region Attributes

		private readonly Database BaseDatos = DatabaseFactory.CreateDatabase();

		#endregion

		#region Methods

		/// <summary>
		/// Selects all records from the Cliente table by a foreign key.
		/// </summary>
		public IList<Cliente> Listar()
		{
			var entidades = new List<Cliente>();
			var comando = BaseDatos.GetStoredProcCommand("SelectAllCliente");

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
                    entidades.Add(new Cliente
                    {
                        IdCliente = lector.GetInt32(lector.GetOrdinal("IdCliente")),
                        UserID = lector.GetGuid(lector.GetOrdinal("UserID")),
                        Dni = lector.GetString(lector.GetOrdinal("Dni")),
                        Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
                        Apellidos = lector.GetString(lector.GetOrdinal("Apellidos")),
                        Ruc = lector.IsDBNull(lector.GetOrdinal("Ruc")) ? default(string) : lector.GetString(lector.GetOrdinal("Ruc")),
                        RazonSocial = lector.IsDBNull(lector.GetOrdinal("RazonSocial")) ? default(string) : lector.GetString(lector.GetOrdinal("RazonSocial")),
                        Direccion = lector.IsDBNull(lector.GetOrdinal("Direccion")) ? default(string) : lector.GetString(lector.GetOrdinal("Direccion")),
                        Email = lector.IsDBNull(lector.GetOrdinal("Email")) ? default(string) : lector.GetString(lector.GetOrdinal("Email")),
                        Telefono = lector.IsDBNull(lector.GetOrdinal("Telefono")) ? default(string) : lector.GetString(lector.GetOrdinal("Telefono")),
                        Celular = lector.IsDBNull(lector.GetOrdinal("Celular")) ? default(string) : lector.GetString(lector.GetOrdinal("Celular")),
                        FechaNacimiento = lector.IsDBNull(lector.GetOrdinal("FechaNacimiento")) ? default(DateTime) : lector.GetDateTime(lector.GetOrdinal("FechaNacimiento")),
                        Sexo = lector.IsDBNull(lector.GetOrdinal("Sexo")) ? default(string) : lector.GetString(lector.GetOrdinal("Sexo")),
                        Ocupacion = lector.IsDBNull(lector.GetOrdinal("Ocupacion")) ? default(string) : lector.GetString(lector.GetOrdinal("Ocupacion")),
                        Foto = lector.IsDBNull(lector.GetOrdinal("Foto")) ? default(string) : lector.GetString(lector.GetOrdinal("Foto")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito")))
                    });
				}
			}
			comando.Dispose();
			return entidades;
		}

		/// <summary>
		/// Selects all records from the Cliente table by a foreign key.
		/// </summary>
		public Cliente Obtener(int idCliente)
		{
			var cliente = default(Cliente);
			var comando = BaseDatos.GetStoredProcCommand("SelectCliente");

			BaseDatos.AddInParameter(comando, "IdCliente", DbType.Int32, idCliente);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				if (lector.Read())
				{
                    cliente = new Cliente
                    {
                        IdCliente = lector.GetInt32(lector.GetOrdinal("IdCliente")),
                        UserID = lector.GetGuid(lector.GetOrdinal("UserID")),
                        Dni = lector.GetString(lector.GetOrdinal("Dni")),
                        Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
                        Apellidos = lector.GetString(lector.GetOrdinal("Apellidos")),
                        Ruc = lector.IsDBNull(lector.GetOrdinal("Ruc")) ? default(string) : lector.GetString(lector.GetOrdinal("Ruc")),
                        Direccion = lector.IsDBNull(lector.GetOrdinal("Direccion")) ? default(string) : lector.GetString(lector.GetOrdinal("Direccion")),
                        Email = lector.GetString(lector.GetOrdinal("Email")),
                        Telefono = lector.IsDBNull(lector.GetOrdinal("Telefono")) ? default(string) : lector.GetString(lector.GetOrdinal("Telefono")),
                        Celular = lector.IsDBNull(lector.GetOrdinal("Celular")) ? default(string) : lector.GetString(lector.GetOrdinal("Celular")),
                        FechaNacimiento = lector.IsDBNull(lector.GetOrdinal("FechaNacimiento")) ? default(DateTime) : lector.GetDateTime(lector.GetOrdinal("FechaNacimiento")),
                        Sexo = lector.IsDBNull(lector.GetOrdinal("Sexo")) ? default(string) : lector.GetString(lector.GetOrdinal("Sexo")),
                        Ocupacion = lector.IsDBNull(lector.GetOrdinal("Ocupacion")) ? default(string) : lector.GetString(lector.GetOrdinal("Ocupacion")),
                        Foto = lector.IsDBNull(lector.GetOrdinal("Foto")) ? default(string) : lector.GetString(lector.GetOrdinal("Foto")),
                        RazonSocial = lector.IsDBNull(lector.GetOrdinal("RazonSocial")) ? default(string) : lector.GetString(lector.GetOrdinal("RazonSocial")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito")))
                    };
				}
			}
			comando.Dispose();
			return cliente;
		}

        public Cliente ObtenerPorDni(string dni)
        {
            var cliente = default(Cliente);
            var comando = BaseDatos.GetStoredProcCommand("SelectClientePorDni");

            BaseDatos.AddInParameter(comando, "Dni", DbType.String, dni);

            using (var lector = BaseDatos.ExecuteReader(comando))
            {
                if (lector.Read())
                {
                    cliente = new Cliente
                    {
                        IdCliente = lector.GetInt32(lector.GetOrdinal("IdCliente")),
                        UserID = lector.GetGuid(lector.GetOrdinal("UserID")),
                        Dni = lector.GetString(lector.GetOrdinal("Dni")),
                        Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
                        Apellidos = lector.GetString(lector.GetOrdinal("Apellidos")),
                        Ruc = lector.IsDBNull(lector.GetOrdinal("Ruc")) ? default(string) : lector.GetString(lector.GetOrdinal("Ruc")),
                        Direccion = lector.IsDBNull(lector.GetOrdinal("Direccion")) ? default(string) : lector.GetString(lector.GetOrdinal("Direccion")),
                        Email = lector.GetString(lector.GetOrdinal("Email")),
                        Telefono = lector.IsDBNull(lector.GetOrdinal("Telefono")) ? default(string) : lector.GetString(lector.GetOrdinal("Telefono")),
                        Celular = lector.IsDBNull(lector.GetOrdinal("Celular")) ? default(string) : lector.GetString(lector.GetOrdinal("Celular")),
                        FechaNacimiento = lector.IsDBNull(lector.GetOrdinal("FechaNacimiento")) ? default(DateTime) : lector.GetDateTime(lector.GetOrdinal("FechaNacimiento")),
                        Sexo = lector.IsDBNull(lector.GetOrdinal("Sexo")) ? default(string) : lector.GetString(lector.GetOrdinal("Sexo")),
                        Ocupacion = lector.IsDBNull(lector.GetOrdinal("Ocupacion")) ? default(string) : lector.GetString(lector.GetOrdinal("Ocupacion")),
                        Foto = lector.IsDBNull(lector.GetOrdinal("Foto")) ? default(string) : lector.GetString(lector.GetOrdinal("Foto")),
                        RazonSocial = lector.IsDBNull(lector.GetOrdinal("RazonSocial")) ? default(string) : lector.GetString(lector.GetOrdinal("RazonSocial")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito")))
                    };
                }
            }
            comando.Dispose();
            return cliente;
        }

        public Cliente ObtenerPorRuc(string ruc)
        {
            var cliente = default(Cliente);
            var comando = BaseDatos.GetStoredProcCommand("SelectClientePorRuc");

            BaseDatos.AddInParameter(comando, "Ruc", DbType.String, ruc);

            using (var lector = BaseDatos.ExecuteReader(comando))
            {
                if (lector.Read())
                {
                    cliente = new Cliente
                    {
                        IdCliente = lector.GetInt32(lector.GetOrdinal("IdCliente")),
                        UserID = lector.GetGuid(lector.GetOrdinal("UserID")),
                        Dni = lector.GetString(lector.GetOrdinal("Dni")),
                        Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
                        Apellidos = lector.GetString(lector.GetOrdinal("Apellidos")),
                        Ruc = lector.IsDBNull(lector.GetOrdinal("Ruc")) ? default(string) : lector.GetString(lector.GetOrdinal("Ruc")),
                        Direccion = lector.IsDBNull(lector.GetOrdinal("Direccion")) ? default(string) : lector.GetString(lector.GetOrdinal("Direccion")),
                        Email = lector.GetString(lector.GetOrdinal("Email")),
                        Telefono = lector.IsDBNull(lector.GetOrdinal("Telefono")) ? default(string) : lector.GetString(lector.GetOrdinal("Telefono")),
                        Celular = lector.IsDBNull(lector.GetOrdinal("Celular")) ? default(string) : lector.GetString(lector.GetOrdinal("Celular")),
                        FechaNacimiento = lector.IsDBNull(lector.GetOrdinal("FechaNacimiento")) ? default(DateTime) : lector.GetDateTime(lector.GetOrdinal("FechaNacimiento")),
                        Sexo = lector.IsDBNull(lector.GetOrdinal("Sexo")) ? default(string) : lector.GetString(lector.GetOrdinal("Sexo")),
                        Ocupacion = lector.IsDBNull(lector.GetOrdinal("Ocupacion")) ? default(string) : lector.GetString(lector.GetOrdinal("Ocupacion")),
                        Foto = lector.IsDBNull(lector.GetOrdinal("Foto")) ? default(string) : lector.GetString(lector.GetOrdinal("Foto")),
                        RazonSocial = lector.IsDBNull(lector.GetOrdinal("RazonSocial")) ? default(string) : lector.GetString(lector.GetOrdinal("RazonSocial")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito")))
                    };
                }
            }
            comando.Dispose();
            return cliente;
        }

        public Cliente ObtenerPorGuid(Guid guid)
        {
            var cliente = default(Cliente);
            var comando = BaseDatos.GetStoredProcCommand("SelectClientePorGuid");

            BaseDatos.AddInParameter(comando, "GuidID", DbType.Guid, guid);

            using (var lector = BaseDatos.ExecuteReader(comando))
            {
                if (lector.Read())
                {
                    cliente = new Cliente
                    {
                        IdCliente = lector.GetInt32(lector.GetOrdinal("IdCliente")),
                        UserID = lector.GetGuid(lector.GetOrdinal("UserID")),
                        Dni = lector.GetString(lector.GetOrdinal("Dni")),
                        Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
                        Apellidos = lector.GetString(lector.GetOrdinal("Apellidos")),
                        Ruc = lector.IsDBNull(lector.GetOrdinal("Ruc")) ? default(string) : lector.GetString(lector.GetOrdinal("Ruc")),
                        Direccion = lector.IsDBNull(lector.GetOrdinal("Direccion")) ? default(string) : lector.GetString(lector.GetOrdinal("Direccion")),
                        Email = lector.GetString(lector.GetOrdinal("Email")),
                        Telefono = lector.IsDBNull(lector.GetOrdinal("Telefono")) ? default(string) : lector.GetString(lector.GetOrdinal("Telefono")),
                        Celular = lector.IsDBNull(lector.GetOrdinal("Celular")) ? default(string) : lector.GetString(lector.GetOrdinal("Celular")),
                        FechaNacimiento = lector.IsDBNull(lector.GetOrdinal("FechaNacimiento")) ? default(DateTime) : lector.GetDateTime(lector.GetOrdinal("FechaNacimiento")),
                        Sexo = lector.IsDBNull(lector.GetOrdinal("Sexo")) ? default(string) : lector.GetString(lector.GetOrdinal("Sexo")),
                        Ocupacion = lector.IsDBNull(lector.GetOrdinal("Ocupacion")) ? default(string) : lector.GetString(lector.GetOrdinal("Ocupacion")),
                        Foto = lector.IsDBNull(lector.GetOrdinal("Foto")) ? default(string) : lector.GetString(lector.GetOrdinal("Foto")),
                        RazonSocial = lector.IsDBNull(lector.GetOrdinal("RazonSocial")) ? default(string) : lector.GetString(lector.GetOrdinal("RazonSocial")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito")))
                    };
                }
            }
            comando.Dispose();
            return cliente;
        }

	    /// <summary>
		/// Saves a record to the Cliente table.
		/// </summary>
		public int Agregar(Cliente cliente)
		{
			var comando = BaseDatos.GetStoredProcCommand("InsertCliente");
			BaseDatos.AddOutParameter(comando, "IdCliente", DbType.Int32, 4);
			BaseDatos.AddInParameter(comando, "UserID", DbType.Guid, cliente.UserID);
			BaseDatos.AddInParameter(comando, "Dni", DbType.String, cliente.Dni);
			BaseDatos.AddInParameter(comando, "Nombre", DbType.String, cliente.Nombre);
			BaseDatos.AddInParameter(comando, "Apellidos", DbType.String, cliente.Apellidos);
			BaseDatos.AddInParameter(comando, "Ruc", DbType.String, cliente.Ruc);
            BaseDatos.AddInParameter(comando, "RazonSocial", DbType.String, cliente.RazonSocial);
			BaseDatos.AddInParameter(comando, "IdDistrito", DbType.Int32, cliente.Distrito.IdDistrito);
			BaseDatos.AddInParameter(comando, "Direccion", DbType.String, cliente.Direccion);
			BaseDatos.AddInParameter(comando, "Email", DbType.String, cliente.Email);
			BaseDatos.AddInParameter(comando, "Telefono", DbType.String, cliente.Telefono);
			BaseDatos.AddInParameter(comando, "Celular", DbType.String, cliente.Celular);
			BaseDatos.AddInParameter(comando, "FechaNacimiento", DbType.DateTime, cliente.FechaNacimiento);
			BaseDatos.AddInParameter(comando, "Sexo", DbType.String, cliente.Sexo);
			BaseDatos.AddInParameter(comando, "Ocupacion", DbType.String, cliente.Ocupacion);
			BaseDatos.AddInParameter(comando, "Foto", DbType.String, cliente.Foto);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Agregar Cliente.");

			var valorDevuelto = (int)BaseDatos.GetParameterValue(comando, "IdCliente");;
			comando.Dispose();
			return valorDevuelto;
		}

		/// <summary>
		/// Updates a record in the Cliente table.
		/// </summary>
		public bool Modificar(Cliente cliente)
		{
			var comando = BaseDatos.GetStoredProcCommand("UpdateCliente");
			BaseDatos.AddInParameter(comando, "IdCliente", DbType.Int32, cliente.IdCliente);
			BaseDatos.AddInParameter(comando, "UserID", DbType.Guid, cliente.UserID);
			BaseDatos.AddInParameter(comando, "Dni", DbType.String, cliente.Dni);
			BaseDatos.AddInParameter(comando, "Nombre", DbType.String, cliente.Nombre);
			BaseDatos.AddInParameter(comando, "Apellidos", DbType.String, cliente.Apellidos);
			BaseDatos.AddInParameter(comando, "Ruc", DbType.String, cliente.Ruc);
            BaseDatos.AddInParameter(comando, "RazonSocial", DbType.String, cliente.RazonSocial);
			BaseDatos.AddInParameter(comando, "IdDistrito", DbType.Int32, cliente.Distrito.IdDistrito);
			BaseDatos.AddInParameter(comando, "Direccion", DbType.String, cliente.Direccion);
			BaseDatos.AddInParameter(comando, "Email", DbType.String, cliente.Email);
			BaseDatos.AddInParameter(comando, "Telefono", DbType.String, cliente.Telefono);
			BaseDatos.AddInParameter(comando, "Celular", DbType.String, cliente.Celular);
			BaseDatos.AddInParameter(comando, "FechaNacimiento", DbType.DateTime, cliente.FechaNacimiento);
			BaseDatos.AddInParameter(comando, "Sexo", DbType.String, cliente.Sexo);
			BaseDatos.AddInParameter(comando, "Ocupacion", DbType.String, cliente.Ocupacion);
			BaseDatos.AddInParameter(comando, "Foto", DbType.String, cliente.Foto);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Modificar Cliente.");

			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the Cliente table by its primary key.
		/// </summary>
		public bool Eliminar(int idCliente)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteCliente");
			BaseDatos.AddInParameter(comando, "IdCliente", DbType.Int32, idCliente);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar Cliente.");
			comando.Dispose();
			return true;
		}

		/// <summary>
		/// Deletes a record from the Cliente table by a foreign key.
		/// </summary>
		public void EliminarPorIdDistrito(int idDistrito)
		{
			var comando = BaseDatos.GetStoredProcCommand("DeleteClienteByIdDistrito");
			BaseDatos.AddInParameter(comando, "IdDistrito", DbType.Int32, idDistrito);

			var resultado = BaseDatos.ExecuteNonQuery(comando);
			if (resultado == 0) throw new Exception("Error al Eliminar Cliente.");
			comando.Dispose();
		}

		/// <summary>
		/// Selects all records from the Cliente table by a foreign key.
		/// </summary>
		public IList<Cliente> ListarPorIdDistrito(int idDistrito)
		{
			var entidades = new List<Cliente>();
			var comando = BaseDatos.GetStoredProcCommand("SelectClienteByIdDistrito");

			BaseDatos.AddInParameter(comando, "IdDistrito", DbType.Int32, idDistrito);

			using (var lector = BaseDatos.ExecuteReader(comando))
			{
				while (lector.Read())
				{
                    entidades.Add(new Cliente
                    {
                        IdCliente = lector.GetInt32(lector.GetOrdinal("IdCliente")),
                        UserID = lector.GetGuid(lector.GetOrdinal("UserID")),
                        Dni = lector.GetString(lector.GetOrdinal("Dni")),
                        Nombre = lector.GetString(lector.GetOrdinal("Nombre")),
                        Apellidos = lector.GetString(lector.GetOrdinal("Apellidos")),
                        Ruc = lector.IsDBNull(lector.GetOrdinal("Ruc")) ? default(string) : lector.GetString(lector.GetOrdinal("Ruc")),
                        Direccion = lector.IsDBNull(lector.GetOrdinal("Direccion")) ? default(string) : lector.GetString(lector.GetOrdinal("Direccion")),
                        Email = lector.GetString(lector.GetOrdinal("Email")),
                        Telefono = lector.IsDBNull(lector.GetOrdinal("Telefono")) ? default(string) : lector.GetString(lector.GetOrdinal("Telefono")),
                        Celular = lector.IsDBNull(lector.GetOrdinal("Celular")) ? default(string) : lector.GetString(lector.GetOrdinal("Celular")),
                        FechaNacimiento = lector.IsDBNull(lector.GetOrdinal("FechaNacimiento")) ? default(DateTime) : lector.GetDateTime(lector.GetOrdinal("FechaNacimiento")),
                        Sexo = lector.IsDBNull(lector.GetOrdinal("Sexo")) ? default(string) : lector.GetString(lector.GetOrdinal("Sexo")),
                        Ocupacion = lector.IsDBNull(lector.GetOrdinal("Ocupacion")) ? default(string) : lector.GetString(lector.GetOrdinal("Ocupacion")),
                        Foto = lector.IsDBNull(lector.GetOrdinal("Foto")) ? default(string) : lector.GetString(lector.GetOrdinal("Foto")),
                        RazonSocial = lector.IsDBNull(lector.GetOrdinal("RazonSocial")) ? default(string) : lector.GetString(lector.GetOrdinal("RazonSocial")),
                        Distrito = DistritoData.Instancia.Obtener(lector.GetInt32(lector.GetOrdinal("IdDistrito")))
                    });
				}
			}
			comando.Dispose();
			return entidades;
		}

		#endregion
	}
}
